package routers

/**
用户登录
*/
import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"ztool/common"
	"ztool/dao"
)

func userLogin(c *gin.Context) {
	//用户名
	userName := c.PostForm("username")
	passwd := c.PostForm("password")

	if err := verifyPassword(userName, passwd); nil != err {
		c.JSON(http.StatusOK, common.RespResult(401, err.Error()))
		return
	}

	//通过，创建token
	token, _ := common.CreateLoginToken(userName)

	user := map[string]interface{}{
		"name":  userName,
		"token": token,
	}

	var data = map[string]interface{}{
		"code": 0,
		"msg":  "登录成功",
		"data": &user,
	}
	c.JSON(http.StatusOK, data)
}

// userLogout 用户注销
func userLogout(c *gin.Context) {
	token := getTokenFromRequest(c)

	claims, err := common.VerifyToken(token)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusOK, common.RespError("注销失败"))
		return
	}

	//添加到黑名单中
	dao.AddBlackList(token, claims.ExpiresAt)

	c.JSON(http.StatusOK, common.RespSuccess("注销失败"))
}

// Authorize 用户认证/**
func authorize() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := getTokenFromRequest(c)
		if "" == token {
			c.Abort()
			c.JSON(http.StatusUnauthorized, common.RespResult(401, "访问未授权"))
			return
		}

		claims, err := common.VerifyToken(token)
		if err != nil {
			// 处理 解析失败
			c.Abort()
			c.JSON(http.StatusUnauthorized, common.RespResult(401, "认证失败"))
			return
		}

		//检查IP,如果传了ip，并且请求ip和配置的不一致，则禁止访问
		if len(claims.Ip) != 0 && c.ClientIP() != claims.Ip {
			c.Abort()
			c.JSON(http.StatusUnauthorized, common.RespResult(401, "IP被限制访问"))
			return
		}

		//检查是否在黑名单
		if dao.GetBlackListFromDB(token) {
			fmt.Println("用户在黑名单中")
			c.Abort()
			c.JSON(http.StatusUnauthorized, common.RespResult(401, "禁用用户"))
			return
		}

		fmt.Printf("验证通过，token: %s user: %s \r\n", token, claims.Username)
		c.Next()
	}
}

//获取token
func getTokenFromRequest(c *gin.Context) string {
	//头中传递
	token := c.GetHeader("token")
	//Get参数中传递
	paramToken := c.Query("token")
	//post参数中传递
	postToken := c.PostForm("token")

	if "" == token {
		if "" == paramToken {
			if "" == postToken {
				return ""
			} else {
				token = postToken
			}
		} else {
			token = paramToken
		}
	}
	return token
}

// 验证用户和密码
func verifyPassword(userName string, passwd string) error {
	//从数据库查询出用户
	dbUsers := dao.GetUserFromDB(&userName)

	if nil == dbUsers {
		//c.JSON(http.StatusOK, gin.H{"code": 401, "msg": "该用户不存在"})
		return errors.New("该用户不存在")
	}

	//比较密码
	formPassword := dao.CreateSHA256(passwd)

	if dbUsers.Password != formPassword {
		return errors.New("用户名或密码错误")
	}

	return nil
}

// 修改用户密码
func changePwd(c *gin.Context) {
	//post参数中传递
	username := c.PostForm("username")
	oldpwd := c.PostForm("oldPwd")
	password := c.PostForm("password")

	if err := verifyPassword(username, oldpwd); nil != err {
		c.JSON(http.StatusOK, common.RespError("旧密码不正确"))
		return
	}

	dao.UpdateUserPwd(password, username)
	c.JSON(http.StatusOK, common.RespSuccess("修改成功"))
}

func loadAnnoLoginRoute(r *gin.Engine) {
	r.POST("/login", userLogin)
}

// loadAuthorPagesRouter 将路由组注册进去
func loadAuthorLoginRouter(r *gin.Engine) {
	//注销
	r.POST("/logout", userLogout)
	//修改密码
	r.POST("/user/changepwd", changePwd)
}
